<html>

<head>
    <!-- $Id: Tomcat-Workers-HowTo.html,v 1.4 2004/02/29 22:42:50 billbarker Exp $ -->
<!--
   Copyright 1999-2004 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->

    <meta http-equiv=Content-Type content="text/html">
    <link rel="stylesheet" href=style.css>
    <style type="text/css">
    td {
        background-color: #E0E0E0;
        vertical-align: text-top;
        border-top: thick black;
        border-right: thick black;
        border-bottom: thick black;
        border-left: thick black;
    }
    th {
        background-color: #d0d0d0;
        border-top: thick black;
        border-right: thick black;
        border-bottom: thick black;
        border-left: thick black;
    }
    table {
        width: 75%;
        border: thick;
        background-color: #000000;
    }
    </style>
<title>Tomcat Workers HowTo</title>
</head>

<body>
<h1>Tomcat workers.properties</h1>

<p>By Gal Shachor <tt>&lt;<a href="mailto:shachor@il.ibm.com">
shachor@il.ibm.com</a>&gt;</tt></p>

<p>A Tomcat worker is a Tomcat instance that is waiting to
execute servlets on behalf of some web server. For example, we can have a web
server such as Apache forwarding servlet requests to a Tomcat process (the
worker) running behind it. </p>

<p>The scenario described above is a very simple one; in fact
one can configure multiple Tomcat workers to serve servlets on behalf of a
certain web server. The reasons for such configuration can be:</p>

<ul>
 <li>We
     want different contexts to be served by different Tomcat workers to
     provide a development environment where all the developers share the same
     web server but own a Tomcat worker of their own.</li>
 <li>We
     want different virtual hosts served by different Tomcat processes to
     provide a clear separation between sites belonging to different companies.</li>
 <li>We
     want to provide load balancing, meaning run multiple Tomcat workers each
     on a machine of its own and distribute the requests between them.</li>
</ul>

<p>There are probably more reasons for having multiple workers
but I guess that this list is enough... </p>

<p>Tomcat workers are defined in a properties file dubbed
workers.properties and this tutorial explains how to work with it.</p>

<h2>Defining Workers</h2>

<p>Defining workers to the Tomcat web server plugin can be done
using a properties file (a sample file named workers.properties is available in
the conf/ directory); the file contains entries of the following form:</p>

<p>worker.list=&lt;a comma separated list of worker names&gt;</p>

<p>For example, <tt>worker.list= ajp12, ajp13</tt></p>

<p>And </p>

<p>worker.&lt;worker name&gt;.&lt;property&gt;=&lt;property
value&gt;</p>

<p>For example, <tt>worker.local.port=8007</tt></p>

<p>When starting up, the web server plugin will instantiate the
workers whose name appears in the worker.list property, these are also the
workers to whom you can map requests. </p>

<p>Each named worker should also have a few entries to provide
additional information on his behalf; this information includes the worker's
type and other related worker information. Currently the following worker types
that exists are (Tomcat 3.2-dev): </p>

<table>
 <tr>
  <th>
  <p>Worker type</p>
  </th>
  <th>
  <p>Description</p>
  </th>
 </tr>
 <tr>
  <td bgcolor="#FeFeFe">ajp12</p>
  </td>
  <td bgcolor="#FeFeFe">
  <p>This worker knows how to forward requests to
  out-of-process Tomcat workers using the ajpv12 protocol.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>ajp13</p>
  </td>
  <td>
  <p>This worker knows how to forward requests to
  out-of-process Tomcat workers using the ajpv13 protocol.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>jni</p>
  </td>
  <td>
  <p>This worker knows how to forward requests to in-process
  Tomcat workers using JNI.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>lb</p>
  </td>
  <td>
  <p>This is a load-balancing worker; it knows how to provide
  round-robin based sticky load balancing with a certain level of
  fault-tolerance.</p>
  </td>
 </tr>
</table>

<p>Defining workers of a certain type should be done with the
following property format:</p>

<p>worker.&lt;worker name&gt;.type=&lt;worker type&gt;</p>

<p>Where worker name is the name assigned to the worker and the
worker type is one of the four types defined in the table (a worker name may
not contain any space (a good naming convention for queue named should follow
the Java variable naming rules).</p>

<p>For example:</p>

<table>
 <tr>
  <th>
  <p>Worker definition</p>
  </th>
  <th>
  <p>Meaning</p>
  </th>
 </tr>
 <tr>
  <td>
  <p>worker.local.type=ajp12</p>
  </td>
  <td>
  <p>Defines a worker named &quot;local&quot; that uses the ajpv12 protocol
  to forward requests to a Tomcat process.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>worker.remote.type=ajp13</p>
  </td>
  <td>
  <p>Defines a worker named &quot;remote&quot; that uses the ajpv13 protocol
  to forward requests to a Tomcat process.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>worker.fast.type=jni</p>
  </td>
  <td>
  <p>Defines a worker named &quot;fast&quot; that uses JNI
  to forward requests to a Tomcat process.</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>worker.loadbalancer.type=lb</p>
  </td>
  <td>
  <p>Defines a worker named &quot;loadbalancer&quot; that 
  loadbalances several Tomcat processes transparently.</p>
  </td>
 </tr>
</table>

<h2>Setting Worker Properties</h2>

<p>After defining the workers you can also specify properties
for them. Properties can be specified in the following manner:</p>

<p>worker.&lt;worker name&gt;.&lt;property&gt;=&lt;property
value&gt;</p>

<p>Each worker has a set of properties that you can set as
specified in the following subsections:</p>

<h3>ajp12 Worker properties</h3>

<p>The ajp12 typed workers forward requests to out-of-process
Tomcat workers using the ajpv12 protocol over TCP/IP sockets. The following
table specifies properties that the ajp12 worker can accept:</p>

<table>
 <tr>
  <th>
  <p>Property name</p>
  </th>
  <th>
  <p>Meaning</p>
  </th>
  <th>
  <p>Example</p>
  </th>
 </tr>
 <tr>
  <td>
  <p>port</p>
  </td>
  <td>
  <p>The port where the Tomcat worker is listening for ajp12
  requests.</p>
  </td>
  <td>
  <p>worker.local.port=8007</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>host</p>
  </td>
  <td>
  <p>The host where the Tomcat worker is listening for ajp12
  requests.</p>
  </td>
  <td>
  <p>worker.local.host=www.x.com</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>lbfactor</p>
  </td>
  <td>
  <p>When working with a load balancer worker, this is the
  load-balancing factor for the worker. (More on this in the lb worker section).</p>
  </td>
  <td>
  <p>worker.local.lbfactor=2.5</p>
  </td>
 </tr>
</table>

<h3>ajp13 Worker properties</h3>

<p>The ajp13 typed workers forward requests to out-of-process
Tomcat workers using the ajpv13 protocol over TCP/IP sockets. The main
difference between ajpv12 and ajpv13 are that:</p>

<ol>
 <li>ajpv13
     is a more binary protocol and it try to compress some of the request data
     by coding frequently used strings as small integers.</li>
 <li>ajpv13
     reuse open sockets and leaves them open for future requests.</li>
 <li>ajpv13
     has special treatment for SSL information so that the container can
     implement SSL related methods such as isSecure().</li>
</ol>



<p>The following table specifies properties that the ajp13
worker can accept:</p>

<table>
 <tr>
  <th>
  <p>Property name</p>
  </th>
  <th>
  <p>Meaning</p>
  </th>
  <th>
  <p>Example</p>
  </th>
 </tr>
 <tr>
  <td>
  <p>port</p>
  </td>
  <td>
  <p>The port where the Tomcat worker is listening for ajp13
  requests.</p>
  </td>
  <td>
  <p>worker.local13.port=8007</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>host</p>
  </td>
  <td>
  <p>The host where the Tomcat worker is listening for ajp13
  requests.</p>
  </td>
  <td>
  <p>worker.local13.host=www.x.com</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>lbfactor</p>
  </td>
  <td>
  <p>When working with a load balancer worker, this is the
  load-balancing factor for the worker. (More on this in the lb worker
  section).</p>
  </td>
  <td>
  <p>worker.local13.lbfactor=2.5</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>cachesize</p>
  </td>
  <td>
  <p>Specifies the number of open socket connections that the
  worker will keep. By default this value is 1, but multithreaded web servers
  such as Apach2.xx, IIS and Netscape will benefit the most by setting this
  value to a higher level (such as the estimated average concurrent users for
  Tomcat)</p>
  </td>
  <td>
  <p>worker.local13.cachesize=30</p>
  </td>
 </tr>
</table>

<h3>lb Worker properties</h3>

<p>The load-balancing worker does not really communicate with
Tomcat workers; instead it is responsible for the management of several
&quot;real&quot; workers. This management includes:</p>

<ul>
 <li>Instantiating
     the workers in the web server.</li>
 <li>Using
     the worker's load-balancing factor, perform weighed-round-robin load
     balancing where high lbfactor means stronger machine (that is going to
     handle more requests)</li>
 <li>Keeping
     requests belonging to the same session executing on the same Tomcat
     worker.</li>
 <li>Identifying
     failed Tomcat workers, suspending requests to them and instead
     fall-backing on other workers managed by the lb worker.</li>
</ul>

<p>The overall result is that workers managed by the same lb
worker are load-balanced (based on their lbfactor and current user session) and
also fall-backed so a single Tomcat process death will not &quot;kill&quot; the
entire site.</p>

<p>The following table specifies properties that the lb worker
can accept:</p>

<table>
 <tr>
  <th>
  <p>Property name</p>
  </th>
  <th>
  <p>Meaning</p>
  </th>
  <th>
  <p>Example</p>
  </th>
 </tr>
 <tr>
  <td>
  <p>balanced_workers</p>
  </td>
  <td>
  <p>A comma separated list of workers that the load balancer
  need to manage. These workers should not appear in the worker.list
  property.</p>
  </td>
  <td>
  <p>worker.loadbalancer.balanced_workers= local13, local12</p>
  </td>
 </tr>
</table>

<h3>jni Worker properties</h3>

<p>The jni worker opens a JVM inside the web server process and
executes Tomcat within it (that is in-process). Following that, messages to and
from the JVM are passed using JNI method calls, this makes the jni worker
faster then the out-of-process workers that need to communicate to the Tomcat
workers by writing AJP messages over TCP/IP sockets.</p>

<p>Note: Since the JVM is multithreaded; the jni worker should
be used only within multithreaded servers such as AOLServer, IIS, Netscape and
Apache2.0. You should also make sure that the threading scheme used by the web
servers match the one used to build the jk web server plugin.</p>

<p>Since the jni worker opens a JVM it can accept many
properties that it forward to the JVM such as the classpath etc. as we can see
in the following table.</p>

<table>
 <tr>
  <th>
  <p>Property name</p>
  </th>
  <th>
  <p>Meaning</p>
  </th>
  <th>
  <p>Example</p>
  </th>
 </tr>
 <tr>
  <td>
  <p>class_path</p>
  </td>
  <td>
  <p>The classpath as used by the in-process JVM. This should
  point to all Tomcats' jar/file files as well as any class or other jar file
  that you want to add to the JVM.</p>

  <p>You should remember to also add Javac to the classpath.
  This can be done in Java2 by adding tools.jar to the classpath. In JDK1.xx
  you should just add classes.zip.</p>

  <p>The class_path property can be given in multiple lines. In
  this case the jk environment will concatenate all the classpath entries
  together by putting path delimiter (&quot;:&quot;/&quot;;&quot;) between the
  entries.</p>
  </td>
  <td>
  <p>worker.localjni.class_path=path-to-some-jarfile</p>
  <p>worker.localjni.class_path=path-to-class-directory</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>cmd_line</p>
  </td>
  <td>
  <p>The command line that is handed over to Tomcats' startup
  code. </p>

  <p>The cmd_line property can be given in multiple lines. In
  this case the jk environment will concatenate all the cmd_line entries
  together by putting spaces between the entries.</p>
  </td>
  <td>
  <p>worker.localjni.cmd_line=-config</p>
  <p>worker.localjni.cmd_line=path-to-tomcats-server.xml-file</p>
  <p>worker.localjni.cmd_line=-home</p>
  <p>worker.localjni.cmd_line=-path-to-tomcat-home</p>

  </td>
 </tr>
 <tr>
  <td>
  <p>jvm_lib</p>
  </td>
  <td>
  <p>Full path to the JVM implementation library. The jni
  worker will use this path to load the JVM dynamically.</p>
  </td>
  <td>
  <p>worker.localjni.jvm_lib=full-path-to-jvm.dll</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>stdout</p>
  </td>
  <td>
  <p>Full path to where the JVM write its System.out</p>
  </td>
  <td>
  <p>worker.localjni.stdout=full-path-to-stdout-file</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>stderr</p>
  </td>
  <td>
  <p>Full path to where the JVM write its System.err</p>
  </td>
  <td>
  <p>worker.localjni.stderr=full-path-to-stderr-file</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>sysprops</p>
  </td>
  <td>
  <p>Java system properties for the JVM</p>
  </td>
  <td>
  <p>worker.localjni.sysprops=some-property</p>
  </td>
 </tr>
 <tr>
  <td>
  <p>ld_path</p>
  </td>
  <td>
  <p>Additional dynamic libraries path (similar in nature to
  LD_LIBRARY_PATH)</p>
  </td>
  <td>
  <p>worker.localjni.ld_path=some-extra-dynamic-library-path</p>
  </td>
 </tr>
</table>

<h2>Property file macros</h2>

<p>Starting with Tomcat3.2 you can define &quot;macros&quot; in
the property files. These macros let you define properties and later on use
them while constructing other properties. For example the following fragment:</p>

<pre>
workers.tomcat_home=d:\tomcat
workers.java_home=d:\sdk\jdk1.2.2
ps=\
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)classes
worker.inprocess.class_path=$(workers.java_home)$(ps)lib$(ps)tools.jar
</pre>

<p>Will end up with the following values for the
worker.inprocess.class_path properties</p>

<pre>
worker.inprocess.class_path= d:\tomcat\classes
worker.inprocess.class_path=d:\sdk\jdk1.2.2\lib\tools.jar
</pre>

<h2>The sample worker.properties</h2>

<p>Since coping with worker.properties on your own is not an
easy thing to do, a sample worker.properties file is bundled along with
Tomcat3.2-dev (and above). The file is meant to be as <b>generic</b> as
possible and it uses the property macros extensively.</p>

<p>The sample worker.properties contains the following high
level definitions:</p>

<ol>
 <li>An
     ajp12 worker that used the host localhost and the port 8007</li>
 <li>An
     ajp13 worker that used the host localhost and the port 8008</li>
 <li>A jni
     worker</li>
 <li>A lb
     worker that load balance the ajp12 and ajp13 workers</li>
</ol>

<p>The ajp12, ajp13 and lb worker definitions can work without
modifying the file. However to make the jni worker come into life you should
set the following properties in the file:</p>

<ul>
 <li>workers.tomcat_home
     - Have it point to your tomcat_home. E.g. wrkers.tomcat_home=d:\tomcat</li>
 <li>workers.java_home
     - Have it point to where you placed your JDK. E.g.
     workers.java_home=c:\jdk1.2.2</li>
 <li>ps - Have it point to the file system
     separator of your OS. E.g. ps=\</li>
</ul>

<p>When you are done, the default jni worker <b>should</b>
work.</p>

</body>
</html>
